package models

import (
	"errors"
	"github.com/go-xorm/xorm"
	"smartLearn/public/common"
	"strconv"
)

type SystemQuestion struct {
	Id          int       `json:"id" xorm:"not null pk autoincr comment('主键') INT(11)"`
	SubjectId        int    `json:"subjectId" xorm:"not null comment('学科主键') INT(11)"`
	TypeId        int    `json:"typeId" xorm:"not null comment('题型主键') INT(11)"`
	SourceId        int    `json:"sourceId" xorm:"not null comment('题目来源') INT(11)"`
	DifStatus        int    `json:"difStatus" xorm:"not null comment('难度') INT(11)"`
	StarStatus        int    `json:"starStatus" xorm:"not null comment('推荐') INT(11)"`
	VerifyStatus        int    `json:"verifyStatus" xorm:"not null comment('审核状态') INT(11)"`
	ValidStatus        int    `json:"validStatus" xorm:"not null comment('有效状态') INT(11)"`
	//TestStatus        int    `json:"testStatus" xorm:"not null comment('做题情况') INT(11)"`
	//Inlibrary        int    `json:"inlibrary" xorm:"not null comment('在题库中') INT(11)"`
	Comment        string    `json:"comment" xorm:"not null comment('试题说明') VARCHAR(100)"`
	Question        string    `json:"question" xorm:"not null comment('试题内容') VARCHAR(4096)"`
	Answer        string    `json:"answer" xorm:"not null comment('试题答案') VARCHAR(4096)"`
}

type OutputQuestion struct {
	Id          int       `json:"id" xorm:"not null pk autoincr comment('主键') INT(11)"`
	SubjectId        int    `json:"subjectId" xorm:"not null comment('学科主键') INT(11)"`
	TypeId        int    `json:"typeId" xorm:"not null comment('题型主键') INT(11)"`
	SourceId        int    `json:"sourceId" xorm:"not null comment('题目来源') INT(11)"`
	DifStatus        int    `json:"difStatus" xorm:"not null comment('难度') INT(11)"`
	StarStatus        int    `json:"starStatus" xorm:"not null comment('推荐') INT(11)"`
	VerifyStatus        int    `json:"verifyStatus" xorm:"not null comment('审核状态') INT(11)"`
	ValidStatus        int    `json:"validStatus" xorm:"not null comment('有效状态') INT(11)"`
	TestStatus        int    `json:"testStatus" xorm:"not null comment('做题情况') INT(11)"`
	Inlibrary        int    `json:"inlibrary" xorm:"not null comment('在题库中') INT(11)"`
	Comment        string    `json:"comment" xorm:"not null comment('试题说明') VARCHAR(100)"`
	Question        string    `json:"question" xorm:"not null comment('试题内容') VARCHAR(4096)"`
	Answer        string    `json:"answer" xorm:"not null comment('试题答案') VARCHAR(4096)"`
}

var systemquestion = "system_question"
func(q *SystemQuestion) GetRow() bool {
	has, err := mEngine.Get(q)
	if err==nil &&  has  {
		return true
	}
	return false
}

func(q *SystemQuestion) GetRowById(questionId int) bool {
	session :=mEngine.Table(systemquestion).
		Where("id =?  " ,questionId)
	total,err:=session.Count(q)

	if err==nil &&  total>0  {
		return true
	}
	return false
}



func (q *SystemQuestion) Update(levelIdsArr[] int,knowledgeIdsArr[] int,imgIds[] string) (int,error){
	session := mEngine.NewSession()
	defer session.Close()
	// add Begin() before any action
	if err := session.Begin(); err != nil {
		// if returned then will rodefer session.Close()llback automatically
		return 0,err
	}
	//var uid int64
	if _, err := mEngine.Where("id = ?", q.Id).Update(q); err != nil {
		return 0,err

	}
	/*
	删除问题阶段表相应的信息
	 */
	questionLevelModel:= SystemQuestionLevel{}
	if err:=questionLevelModel.DeleteByQuestionId(q.Id);err!=nil{
		return 0,err
	}

	/*
		删除问题知识点表相应的信息
	*/
	questionKnowledgeModel:= SystemQuestionKnowledge{}
	if err:=questionKnowledgeModel.DeleteByQuestionId(q.Id);err!=nil{
		return 0,err
	}

	/*
		删除问题题目图片信息
	*/
	questionImageModel:= SystemQuestionImage{}
	if err:=questionImageModel.DeleteByQuestionId(q.Id);err!=nil{
		return 0,err
	}

	for _,levelId:=range levelIdsArr {
		levelModel := SystemLevel{}
		levelModel.Id = levelId
		has := levelModel.GetRow()
		if !has {
			//如果阶段不存在，忽略
			continue
		}

		questionLevelModel := SystemQuestionLevel{QuestionId: q.Id, LevelId: levelId}

		has, err := session.Get(&questionLevelModel)
		if err != nil {
			return 0, err
		}
		//如果知识点阶段不存在，添加知识点阶段
		if !has {
			_, err = session.Insert(&questionLevelModel)
			if err != nil {
				return 0, err
			}
		}

	}

	for _,knowledgeId:=range knowledgeIdsArr {
		knowledgeModel := SystemKnowledge{}
		knowledgeModel.Id = knowledgeId
		has := knowledgeModel.GetRow()
		if !has {
			//如果知识点不存在，忽略
			continue
		}

		questionKnowledgeModel := SystemQuestionKnowledge{QuestionId: q.Id, KnowledgeId: knowledgeId}

		has, err := session.Get(&questionKnowledgeModel)
		if err != nil {
			return 0, err
		}
		//如果知识点阶段不存在，添加知识点阶段
		if !has {
			_, err = session.Insert(&questionKnowledgeModel)
			if err != nil {
				return 0, err
			}
		}

	}

	//数组变成集合，去重
	var imgIdSet = make(map[string]string) //make定义
	for _,imgId:=range imgIds {
		imgIdSet[imgId]=imgId
	}

	for imgId, _ := range imgIdSet{
		questionImageModel := SystemQuestionImage{QuestionId: q.Id, ImgId: imgId}

		has, err := session.Get(&questionImageModel)
		if err != nil {
			return 0, err
		}
		//如果问题图片记录不存在，添加问题图片记录
		if !has {
			_, err = session.Insert(&questionImageModel)
			if err != nil {
				return 0, err
			}
		}
	}







	return q.Id,session.Commit()
}



func (q *SystemQuestion) Add(levelIdsArr[] int,knowledgeIdsArr[] int,imgIds[] string) (int,error){
	session := mEngine.NewSession()
	defer session.Close()
	// add Begin() before any action
	if err := session.Begin(); err != nil {
		// if returned then will rodefer session.Close()llback automatically
		return 0,err
	}
	//var uid int64

	_,err:=session.Insert(q)
	if err!=nil {
		return 0,err
	}

	/*
	if q.Id,err =mEngine.Exec("insert into "+systemquestion+"  (id,subject_id,type_id,source_id,dif_status,star_status,verify_status,valid_status,question,answer,comment) values (0,?,?,?,?,?,?,?,?,?,?)",
		q.SubjectId,q.TypeId,q.SourceId,q.DifStatus,q.StarStatus,
		q.VerifyStatus,q.ValidStatus,q.Question,q.Answer,q.Comment); err != nil {
		return 0,err
	}*/

	for _,levelId:=range levelIdsArr {
		levelModel := SystemLevel{}
		levelModel.Id = levelId
		has := levelModel.GetRow()
		if !has {
			//如果阶段不存在，忽略
			continue
		}

		questionLevelModel := SystemQuestionLevel{QuestionId: q.Id, LevelId: levelId}

		has, err := session.Get(&questionLevelModel)
		if err != nil {
			return 0, err
		}
		//如果知识点阶段不存在，添加知识点阶段
		if !has {
			_, err = session.Insert(&questionLevelModel)
			if err != nil {
				return 0, err
			}
		}

	}

	for _,knowledgeId:=range knowledgeIdsArr {
		knowledgeModel := SystemKnowledge{}
		knowledgeModel.Id = knowledgeId
		has := knowledgeModel.GetRow()
		if !has {
			//如果知识点不存在，忽略
			continue
		}

		questionKnowledgeModel := SystemQuestionKnowledge{QuestionId: q.Id, KnowledgeId: knowledgeId}

		has, err := session.Get(&questionKnowledgeModel)
		if err != nil {
			return 0, err
		}
		//如果知识点阶段不存在，添加知识点阶段
		if !has {
			_, err = session.Insert(&questionKnowledgeModel)
			if err != nil {
				return 0, err
			}
		}

	}


	//数组变成集合，去重
	var imgIdSet = make(map[string]string) //make定义
	for _,imgId:=range imgIds {
		imgIdSet[imgId]=imgId
	}

	for imgId, _ := range imgIdSet{
		questionImageModel := SystemQuestionImage{QuestionId: q.Id, ImgId: imgId}

		has, err := session.Get(&questionImageModel)
		if err != nil {
			return 0, err
		}
		//如果问题图片记录不存在，添加问题图片记录
		if !has {
			_, err = session.Insert(&questionImageModel)
			if err != nil {
				return 0, err
			}
		}
	}

	return q.Id,session.Commit()
}
func  (q *SystemQuestion) getSimpleByQuestionIdsSession(questionIds string, testStatus string, userId string) (*xorm.Session,error){
	strQuestionIds:="(" + questionIds +")"
	session:=mEngine.Table(systemquestion).Where(systemquestion+".id in  "+ strQuestionIds)
	if userId!="" {
		//说明是用户进来的查询



		intUserId,err:=strconv.Atoi(userId)
		if err!=nil{
			return session,err
		}
		session=session.Join("LEFT OUTER", userquestion, userquestion+".question_id= "+systemquestion+".id")

		if (testStatus!="") &&  (testStatus!="{}"){
			intTestStatus,err:=strconv.Atoi(testStatus)
			if err!=nil{
				return session,err
			}
			session=session.Where(userquestion+".test_status = ? ",intTestStatus)
			session=session.Where(userquestion+".user_id = ? ",intUserId)
		}



	}
	return session,nil
}
func  (q *SystemQuestion)GetSimpleByQuestionIds(questionIds string, testStatus string, userId string, paging *common.Paging)([]OutputQuestion,error){
	var err error

	var questions [] OutputQuestion
	session,err:=q.getSimpleByQuestionIdsSession(questionIds,testStatus,userId)
	if err!=nil{
		return questions ,err
	}
	paging.Total,err = session.Count(q)

	paging.GetPages()
	if paging.Total<1 {
		return questions,err
	}

	session1,err:=q.getSimpleByQuestionIdsSession(questionIds,testStatus,userId)
	if err!=nil{
		return questions ,err
	}
	if userId!=""{
		//从用户来的检索
		err=session1.
			Cols(systemquestion+".id",systemquestion+".subject_id",
			systemquestion+".type_id",systemquestion+".source_id",systemquestion+".dif_status",systemquestion+".star_status",
			systemquestion+".comment",userquestion+".test_status").
			Limit(int(paging.PageSize),int(paging.StartNums)).Find(&questions)

		//再查询user_library表看看是不是再库里
		userLibraryModel:=UserLibrary{}
		for index,_:=range questions {
			userLibraryModel.UserId,err=strconv.Atoi(userId)
			userLibraryModel.Id=0
			if err!=nil{
				return questions,err
			}
			userLibraryModel.QuestionId=questions[index].Id
			userLibraryModel.Inlibrary=1
			if userLibraryModel.GetRow() {
				questions[index].Inlibrary=1
			}else{
				questions[index].Inlibrary=0
			}


		}
	}else{
		err=session1.
			Cols(systemquestion+".id",systemquestion+".subject_id",systemquestion+".type_id",
			systemquestion+".source_id",systemquestion+".dif_status",systemquestion+".star_status",
			systemquestion+".valid_status",systemquestion+".verify_status",systemquestion+".comment").
			Limit(int(paging.PageSize),int(paging.StartNums)).Find(&questions)
	}


	return questions,err

}

func  (q *SystemQuestion) getSimpleByQuestionInputSession(levelIds string ,knowledgeIds string,testStatus string,userId string) (*xorm.Session,error){
	strLevelIds:="("+levelIds+")"
	session:=mEngine.Table(systemquestion).
		Distinct(systemquestion+".id",systemquestion+".subject_id",systemquestion+".type_id",systemquestion+".source_id",systemquestion+".dif_status",systemquestion+".star_status",systemquestion+".valid_status",systemquestion+".verify_status",systemquestion+".comment").
		Join("INNER", systemquestionlevel, systemquestionlevel+".question_id= "+systemquestion+".id").
		Where(systemquestion+".subject_id = ?",q.SubjectId).
		Where(systemquestionlevel+".level_id in " + strLevelIds).
		Where(systemquestion+".verify_status = ? " ,q.VerifyStatus).
		Where(systemquestion+".valid_status = ? " ,q.ValidStatus)

	if q.TypeId!=0{
		session=session.Where(systemquestion+".type_id = ?",q.TypeId)
	}
	if q.SourceId!=0{
		session=session.Where(systemquestion+".source_id = ?",q.SourceId)
	}
	if q.DifStatus!=0{
		session=session.Where(systemquestion+".dif_status = ?",q.DifStatus)
	}
	if q.StarStatus!=0{
		session=session.Where(systemquestion+".star_status = ?",q.StarStatus)
	}
	if q.Comment!=""{
		session=session.Where(systemquestion+".comment like ?",q.Comment+"%")
	}




	if knowledgeIds!=""{
		strKnowledgeIds:="("+knowledgeIds+")"
		session=session.Join("INNER", systemquestionknowledge, systemquestionknowledge+".question_id= "+systemquestion+".id").
			Where(systemquestionknowledge+".knowledge_id in " + strKnowledgeIds)
	}

	if userId!=""{
		//说明是用户进来的查询


		intUserId,err:=strconv.Atoi(userId)
		if err!=nil{
			return session,err
		}
		//session=session.Join("LEFT OUTER", userlibrary, userlibrary+".question_id= "+systemquestion+".id")
		//session=session.Where(userlibrary+".user_id = ? ",intUserId)
		session=session.Join("LEFT OUTER", userquestion, userquestion+".question_id= "+systemquestion+".id")

		if (testStatus!="") &&  (testStatus!="{}"){
			intTestStatus,err:=strconv.Atoi(testStatus)
			if err!=nil{
				return session,err
			}
			session=session.Where(userquestion+".test_status = ? ",intTestStatus)
			session=session.Where(userquestion+".user_id = ? ",intUserId)
		}

	}

	return session,nil
}
func  (q *SystemQuestion)GetSimpleByQuestionInput(levelIds string ,knowledgeIds string,testString string ,userId string, paging *common.Paging)([]OutputQuestion,error){
	var questions [] OutputQuestion
	session,err:=q.getSimpleByQuestionInputSession(levelIds,knowledgeIds,testString,userId)
	if err!=nil{
		return questions,err
	}

	paging.Total,err=  session.Count(q)
	paging.GetPages()


	if err!=nil{
		return questions,err
	}
	if paging.Total<1{
		return questions,err
	}
	session1,err:=q.getSimpleByQuestionInputSession(levelIds,knowledgeIds,testString,userId)
	if err!=nil{
		return questions,err
	}

	if userId!=""{
		//从用户来的检索
		err=session1.
			Cols(systemquestion+".id",systemquestion+".subject_id",
				systemquestion+".type_id",systemquestion+".source_id",systemquestion+".dif_status",systemquestion+".star_status",
				systemquestion+".comment",userquestion+".test_status"  ).
			Limit(int(paging.PageSize),int(paging.StartNums)).Find(&questions)
		//再查询user_library表看看是不是再库里
		userLibraryModel:=UserLibrary{}
		for index,_:=range questions {
			userLibraryModel.UserId,err=strconv.Atoi(userId)
			userLibraryModel.Id=0
			if err!=nil{
				return questions,err
			}
			userLibraryModel.QuestionId=questions[index].Id
			userLibraryModel.Inlibrary=1
			if userLibraryModel.GetRow() {
				questions[index].Inlibrary=1
			}else{
				questions[index].Inlibrary=0
			}


		}





	}else{
		err=session1.
			Cols(systemquestion+".id",systemquestion+".subject_id",systemquestion+".type_id",
			systemquestion+".source_id",systemquestion+".dif_status",systemquestion+".star_status",
			systemquestion+".valid_status",systemquestion+".verify_status",systemquestion+".comment").
			Limit(int(paging.PageSize),int(paging.StartNums)).Find(&questions)
	}



	return questions,err

}

func  (q *SystemQuestion)GetById(id int)(SystemQuestion,error){



	var questions []SystemQuestion
	err:=mEngine.Table(systemquestion).
		Cols("id","subject_id","type_id","source_id","dif_status","star_status","verify_status","valid_status","comment","question","answer").
			Where("id =?  " ,id).Find(&questions)
	if err != nil {
		return *q, err
	}
	if len(questions)==0{

		return *q,errors.New("no user")
	}
	return questions[0],err

}




func (q *SystemQuestion) DeleteById() error{

	session := mEngine.NewSession()
	defer session.Close()
	// add Begin() before any action
	if err := session.Begin(); err != nil {
		// if returned then will rodefer session.Close()llback automatically
		return err
	}
	/*
	数据库设置了级连删除
	*/
	if _, err := mEngine.Where("id = ?", q.Id).Delete(q); err != nil {
		return err
	}

	//删除孤立的试卷
	if _, err :=mEngine.Exec("delete from "+userexam+" where not exists (select 1 from "+userexamquestion+" where "+userexamquestion+".exam_id ="+userexam+".id )"); err != nil {
		return err

	}
	return session.Commit()
}
func (q *SystemQuestion) UpdateVerifyStatus(ids string,verifyStatus int) error{
	idsstr:="("+ids+")"
	session := mEngine.NewSession()
	defer session.Close()
	// add Begin() before any action
	if err := session.Begin(); err != nil {
		// if returned then will rodefer session.Close()llback automatically
		return err
	}


	if _, err := mEngine.Exec("update "+systemquestion+" set verify_status=? where id in " + idsstr,verifyStatus ); err != nil {
		return err
	}
	return session.Commit()
}

func (q *SystemQuestion) UpdateValidStatus(ids string,validStatus int) error{
	idsstr:="("+ids+")"
	session := mEngine.NewSession()
	defer session.Close()
	// add Begin() before any action
	if err := session.Begin(); err != nil {
		// if returned then will rodefer session.Close()llback automatically
		return err
	}


	if _, err := mEngine.Exec("update "+systemquestion+" set valid_status=? where id in " + idsstr,validStatus ); err != nil {
		return err
	}
	return session.Commit()
}

func  (q *SystemQuestion)GetQuestionByQuestionIds(questionIds string)([]SystemQuestion,error){

	var questions []SystemQuestion
	strQuestionIds:="(" + questionIds +")"
	err:=mEngine.Where(systemquestion+".id in  "+ strQuestionIds).Cols("id","question").Find(&questions)
	return questions,err

}

func  (q *SystemQuestion)GetAnswerByQuestionIds(questionIds string)([]SystemQuestion,error){

	var questions []SystemQuestion
	strQuestionIds:="(" + questionIds +")"
	err:=mEngine.Where(systemquestion+".id in  "+ strQuestionIds).Cols("id","answer").Find(&questions)
	return questions,err

}


